/*************************************************************************
    > File Name: 7.producer_sem.c
    > Author: Ykk
    > Mail: 3393579535@qq.com 
    > Created Time: 2023年05月13日 星期六 21时12分56秒
 ************************************************************************/

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>

typedef	struct _node_t{
	int  date;
	struct _node_t *next;
}node_t;

node_t *head = NULL;

//容器个数
sem_t sem_producer;
//销售个数
sem_t sem_customer;

//生产者线程
void *producer(void *arg)
{
	//循环生产产品
	while(1){
	
		//申请一个资源
		sem_wait(&sem_producer);

		//分配节点空间
		node_t *new = malloc(sizeof(node_t));
		if(NULL == new)
		{
			printf("malloc failed...\n");
			break;
		}	
		memset(new,0,sizeof(node_t));

		new->date = random()%100+1;
		new->next = NULL;

		new->next = head;
		head = new;
		printf("生产者生产%d\n",new->date);

	    sem_post(&sem_customer);

		sleep(random()%3+1);
	}
	pthread_exit(NULL);
}
//消费者线程
void *customer(void *arg)
{
	node_t *tmp = NULL;
	//循环消费
	while(1)
	{
		sem_wait(&sem_customer);
		if(NULL == head)
		{
			printf("产品链表为空....先休息两秒\n");
		}

		//头删
		tmp = head;
		head = head->next;
		printf("消费者消费%d\n",tmp->date);
		free(tmp);

		sem_post(&sem_producer);

		sleep(random()%3+1);
	}
	pthread_exit(NULL);
}
//生产者消费者模型 条件变量的模型
int main()
{
	pthread_t tid[6];
	int ret = -1;
	int i = 0;

	srandom(getpid());

	ret = sem_init(&sem_producer,0,8);
	if(0 != ret)
	{
		printf("sem_init failed...\n");
		return 1;
	}
	ret = sem_init(&sem_customer,0,0);
	if(0 != ret)
	{
		printf("sem_init failed...\n");
		return 1;
	}
	//创建线程 生产者线程 消费者线程
	for(i = 0;i < 6;i++)
	{
		if(i < 3)
		{
			pthread_create(&tid[i],NULL,producer,NULL);
		}
		else
		{	
			pthread_create(&tid[i],NULL,customer,NULL);
		}
	}

	//回收线程资源
	for(i = 0;i < 6;i++)
	{
		pthread_join(tid[i],NULL);
	}

	sem_destroy(&sem_producer);
	sem_destroy(&sem_customer);

	return 0;
}
